package com.gaming.glb;

import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.sprite.BaseSprite;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.opengl.texture.region.BaseTextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegion;

import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

public class PhysicBall {
	
	private boolean isMoving = false;
	private PhysicsWorld physicsWorld;
	private BaseTextureRegion baseTextureRegion;

    //calculated properties
	private float width;
	private float height;
	
	private BaseSprite newEntity;

	//physical properties
    protected boolean havePhysicsConnector;
    protected Body newBody;  
	
	/************************************************************/
	private float mCameraWidth;
	private float mCameraHeight;
	private IOnPhysicBallLeaveSceneListener mOnPhysicBallLeaveSceneListener;
	
	public void setOnPhysicBallLeaveSceneListener(final IOnPhysicBallLeaveSceneListener pOnPhysicBallLeaveSceneListener) {
		this.mOnPhysicBallLeaveSceneListener = pOnPhysicBallLeaveSceneListener;
	}	
	
	public IOnPhysicBallLeaveSceneListener getOnPhysicBallLeaveSceneListener() {
		return this.mOnPhysicBallLeaveSceneListener;
	}	
	
	public boolean hasOnCatCatchTheBallListener() {
		return this.mOnPhysicBallLeaveSceneListener != null;
	}
	
	public static interface IOnPhysicBallLeaveSceneListener {
		public boolean onLeaveScene();		
	}	
	/************************************************************/	
	
	public PhysicBall(PhysicsWorld pPhysicsWorld, TextureRegion pBallTextureRegion, float pCameraWidth, float pCameraHeight) {			
		this.mCameraWidth= pCameraWidth;
		this.mCameraHeight = pCameraHeight;
		this.physicsWorld = pPhysicsWorld;	  
		this.baseTextureRegion = pBallTextureRegion;
	    
		this.width = this.baseTextureRegion.getWidth();
		this.height = this.baseTextureRegion.getHeight();
	}
	
	//@Override
	public void attachToScene(float posX, float posY, Scene scene) {		
		this.newEntity = new Sprite(
				posX, 
				posY, 
				(TextureRegion) this.baseTextureRegion
			);	    	
			
	    	scene.attachChild(this.newEntity);
			
	    	scene.registerUpdateHandler(new IUpdateHandler(){
				@Override
				public void reset() { }

				@Override
				public void onUpdate(final float pSecondsElapsed) 
				{
					if (((getPositionX() > mCameraWidth) ||
						(getPositionX() < 0) ||					
						(getPositionY() > mCameraHeight)) && isMoving())				
					{
						newEntity.getX();
						newEntity.getY();
						if(mOnPhysicBallLeaveSceneListener != null) {
							mOnPhysicBallLeaveSceneListener.onLeaveScene();						
						}
					}
				}
			});
	}	
	
	public void setVelocity(final float velocityX, final float velocityY) {	
		//fixture definition
        final FixtureDef ballFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.85f);
        
        //physics
    	newBody = PhysicsFactory.createCircleBody(this.physicsWorld, this.newEntity, BodyType.DynamicBody, ballFixtureDef);          
        this.physicsWorld.registerPhysicsConnector(new PhysicsConnector(this.newEntity, newBody, true, true)); 
        
        //velocity
        newBody.setLinearVelocity(velocityX, velocityY);
        
        this.isMoving = true;        
        this.havePhysicsConnector = true;	      		
	}
	
	public void setRotation(final float rotation) {
		if (!this.havePhysicsConnector) {
			this.newEntity.setRotation(rotation);
		}
	}
	
	public boolean isMoving() {
		return isMoving;		
	}
	
	public void setPosition(final float posX, final float posY) {
		
		if (!this.havePhysicsConnector) {
			this.newEntity.setPosition(posX - (this.width/2), posY - (this.height/2));
		}
	}
	
	public float getPositionX()	{
		return this.newEntity.getX();
	}
	
	public float getPositionY()	{
		return this.newEntity.getY();
	}
	
	public Body getBody(){
		return this.newBody;
	}

	public BaseSprite getSprite(){
		return newEntity;
	}

	public void stopMoving() {
		this.getSprite().setVisible(false);
		this.newBody.setLinearVelocity(0, 0);
		this.isMoving = false;
	}	
}	
	
